package com.edu.bean;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.*;

/*
 * @Author:mx
 * @Date:2025/11/7-14:59:53
 */
public class MyIOC3 {

    private Map<String, Object> box;

    Document document;

    public MyIOC3(String path) {
        box = new HashMap<>();
        SAXReader reader = new SAXReader();
        try {
            document = reader.read(MyIOC3.class.getClassLoader().getResourceAsStream(path));
        } catch (DocumentException e) {
            System.out.println(path + "不存在");
            e.printStackTrace();
        }
        init();
    }

    /*根据 xml文件 创建对象 */
    public void init() {
        List<Node> beans = document.selectNodes("//bean");
        for (Node bean : beans) {
            String beanId = bean.valueOf("@id");
            String className = bean.valueOf("@class");
            try {
                Class<?> aClass = Class.forName(className);
                Object o = aClass.newInstance();
                box.put(beanId,o);
                //对象创建出来之后 接着去填充这个 节点力里的 属性

            } catch (ClassNotFoundException e) {
                System.out.println(className+"类型不存在");
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        //填充属性
        setAttr();
    }

    public void setAttr(){
        Set<String> beanIds = box.keySet();
        for (String beanId : beanIds) {
            Node beanNode = document.selectSingleNode("//beans/bean[@id='"+beanId+"']");
            Object o = box.get(beanId);
            List<Node> attrs = beanNode.selectNodes("property");
            Class aClass = o.getClass();
            for (Node node : attrs) {
                String propertyName = node.valueOf("@name");
                String propertyValue = node.valueOf("@value");
                String ref = node.valueOf("@ref");
                Field field = null;
                try {
                    if(propertyValue != null && !propertyValue.isEmpty()){
                        field = aClass.getDeclaredField(propertyName);
                        field.setAccessible(true);
                        Class targetClass = field.getType();
                        field.set(o,transType(propertyValue,targetClass));
                    }
                    if(ref != null && !ref.isEmpty()){
                        field = aClass.getDeclaredField(propertyName);
                        field.setAccessible(true);
                        Class targetClass = field.getType();
                        field.set(o,box.get(ref));
                    }

                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }
        }

    }
    public Object getBean(Class clazz) {
        for (String s : box.keySet()) {
            Object o = box.get(s);
            if (o.getClass() == clazz) {
                return o;
            }
        }
        return null;
    }

    public Object getBean(String beanId) {
        return box.get(beanId);
    }

    public Object transType(String str,Class targetClass){
        if(targetClass == int.class){
            return Integer.parseInt(str);
        }
        if(targetClass == float.class){
            return Float.parseFloat(str);
        }
        return str;
    }
}
